package com.hrpc.channelHandler.handler;

import com.hrpc.compress.Compressor;
import com.hrpc.compress.CompressorFactory;
import com.hrpc.hRpcBootStarp;
import com.hrpc.serialize.Serialize;
import com.hrpc.serialize.SerializeFactory;
import com.hrpc.transport.message.MessageFormatConstant;
import com.hrpc.transport.message.RequestPayload;
import com.hrpc.transport.message.hRpcRequest;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * 报文的内容：
 * 4B（magic）--->hrpc.getByte()
 * 1B(version)--->1
 * 2B(header length)--->首部的长度
 * 4B(full length)--->报文总长度 解决粘包问题：定长/自己设置长度进行获取
 * 1B(serialize) 序列化
 * 1B(compress) 压缩
 * 1B(requestType) 请求类型
 * 8B(requestId) 请求ID
 * body 长度不定，可以使用full_length - header_length 来计算
 * 出站时第一个经过的处理器
 */
public class hRpcRequestEncoder extends MessageToByteEncoder<hRpcRequest> {

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, hRpcRequest hRpcRequest, ByteBuf byteBuf) throws Exception {
        //封装byteBuf
        byteBuf.writeBytes(MessageFormatConstant.MAGIC);
        //一个字节的版本号
        byteBuf.writeByte(MessageFormatConstant.VERSION);
        //2个字节的头部长度
        byteBuf.writeShort(MessageFormatConstant.HEADER_LENGTH);
        //writeIndex向右移动几位，但是不写
        byteBuf.writerIndex(byteBuf.writerIndex()+MessageFormatConstant.FULL_FIELD_LENGTH);
        //3个类型
        byteBuf.writeByte(hRpcRequest.getRequestType());
        byteBuf.writeByte(hRpcRequest.getSerializeType());
        byteBuf.writeByte(hRpcRequest.getCompressType());
        //8字节的请求ID
        byteBuf.writeLong(hRpcRequest.getRequestId());
        //时间戳
        byteBuf.writeLong(hRpcRequest.getTimeStamp());
//        //如果是心跳请求，独立处理一下总长度
        //写入请求体（RequestPayLoad）
        //1.根据配置的序列化方式进行序列化，
        //怎么实现序列化？1.工具类 耦合性很高，如果以后我想替换序列化的方式，很难，要抽象
        byte[] bodyBytes = null;
        if (hRpcRequest.getRequestPayload() != null){
            Serialize serialize= SerializeFactory.getSerialize(hRpcRequest.getSerializeType()).getImpl();
            bodyBytes = serialize.serialize(hRpcRequest.getRequestPayload());

            //2.序列化结束后根据配置压缩方式进行压缩
            Compressor compressor= CompressorFactory.getCompressor(hRpcRequest.getCompressType()).getImpl();
            bodyBytes=compressor.compress(bodyBytes);
        }
//        byte[] bodyBytes = getBodyBytes(hRpcRequest.getRequestPayload());
        if (bodyBytes != null){
            byteBuf.writeBytes(bodyBytes);
        }
        int bodyLength = bodyBytes==null ? 0 : bodyBytes.length;
        //重新处理报文的总长度
        //先保存当前写指针的位置
        int index = byteBuf.writerIndex();
        //将写指针的位置移动到总长度的位置上
        byteBuf.writerIndex(MessageFormatConstant.MAGIC.length +
                MessageFormatConstant.VERSION_LENGTH +
                MessageFormatConstant.HEADER_LENGTH_LENGTH);
        byteBuf.writeInt(MessageFormatConstant.HEADER_LENGTH+ bodyLength);
        //将写指针归位
        byteBuf.writerIndex(index);
    }


}
